package adapletplugin.editors;

import objects.AdapletConstants;
import objects.Table;

import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.FormToolkit;

import adapletplugin.dialogs.NewColumnDialog;

public class TableEditor extends AbstractSubEditor
{
	private Text fTableText;
	private Button fNewColumnButton;

	private TableViewer fColumnsTable;
	private TableViewer fStringSizeTable;

	private objects.Table fTableFocus;

	public TableEditor(ScrolledComposite composite, FormToolkit toolkit, MapFileEditor editor)
	{
		super(composite, toolkit, editor);
	}

	@Override
	protected void create()
	{
		Composite row = fToolkit.createComposite(fSubComposite);
		row.setLayout(new GridLayout(2, false));
		row.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

		fToolkit.createLabel(row, "Table Name:");
		fTableText = fToolkit.createText(row, "", SWT.BORDER | SWT.READ_ONLY);
		fTableText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		fTableText.addModifyListener(createModifyLister_Name());

		fNewColumnButton = fToolkit.createButton(fSubComposite, "Add Column", SWT.PUSH);
		fNewColumnButton.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, false, false));
		fNewColumnButton.addSelectionListener(createNewColumnSelectListener());

		fColumnsTable = new TableViewer(fSubComposite, SWT.BORDER | SWT.V_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION);
		fColumnsTable.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		fColumnsTable.setContentProvider(new ColumnsTableContentProvider());
		fColumnsTable.setLabelProvider(new ColumnsTableLabelProvider());

		TableColumn tabCol = new TableColumn(fColumnsTable.getTable(), SWT.NONE);
		tabCol.setText("Column Name");
		tabCol.setMoveable(false);
		tabCol.setWidth(100);

		tabCol = new TableColumn(fColumnsTable.getTable(), SWT.RIGHT);
		tabCol.setText("Column Type");
		tabCol.setMoveable(false);
		tabCol.setWidth(100);
		tabCol.setAlignment(SWT.RIGHT);

		fColumnsTable.getTable().setHeaderVisible(true);

		fToolkit.createLabel(fSubComposite, "Sizes of Largestring columns");
		fStringSizeTable = new TableViewer(fSubComposite, SWT.BORDER | SWT.V_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION);
		fStringSizeTable.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		fStringSizeTable.setContentProvider(new StringSizeContentProvider());
		fStringSizeTable.setLabelProvider(new StringSizeLabelProvider());

		tabCol = new TableColumn(fStringSizeTable.getTable(), SWT.NONE);
		tabCol.setText("Column Name");
		tabCol.setMoveable(false);
		tabCol.setWidth(100);

		tabCol = new TableColumn(fStringSizeTable.getTable(), SWT.RIGHT);
		tabCol.setText("String Length");
		tabCol.setMoveable(false);
		tabCol.setWidth(100);
		tabCol.setAlignment(SWT.RIGHT);

		fStringSizeTable.getTable().setHeaderVisible(true);
	}

	private class StringSizeLabelProvider extends LabelProvider implements ITableLabelProvider
	{

		@Override
		public Image getColumnImage(Object element, int columnIndex)
		{
			return null;
		}

		@Override
		public String getColumnText(Object element, int columnIndex)
		{
			String sColName = (String) element;

			if (columnIndex == 0)
			{
				return sColName;
			}
			else if (columnIndex == 1)
			{
				return fTableFocus.getSizeForLargeColumn(sColName);
			}

			return "ERROR: NAME NOT FOUND";
		}

	}

	private class ColumnsTableLabelProvider extends LabelProvider implements ITableLabelProvider
	{

		@Override
		public Image getColumnImage(Object element, int columnIndex)
		{
			return null;
		}

		@Override
		public String getColumnText(Object element, int columnIndex)
		{
			String sColName = (String) element;

			if (columnIndex == 0)
			{
				return sColName;
			}
			else if (columnIndex == 1)
			{
				return AdapletConstants.convertTypeToString(fTableFocus.getTypeForColumn(sColName));
			}

			return "ERROR: NAME NOT FOUND";
		}

	}

	private class StringSizeContentProvider implements IStructuredContentProvider
	{

		@Override
		public void dispose()
		{

		}

		@Override
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
		{

		}

		@Override
		public Object[] getElements(Object inputElement)
		{
			return ((StringSizeTableInput) inputElement).getData();
		}

	}

	private SelectionListener createNewColumnSelectListener()
	{
		return new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e)
			{
				Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();

				NewColumnDialog dialog = new NewColumnDialog(shell);

				dialog.create();
				dialog.open();

				if (dialog.getReturnCode() == Window.OK)
				{
					fTableFocus.addColumn(dialog.getColumnName(), dialog.getColumnType(), dialog.getColumnSize());

					fColumnsTable.refresh();
					fStringSizeTable.refresh();

					fEditor.refresh();
				}
			}
		};
	}

	private class ColumnsTableContentProvider implements IStructuredContentProvider
	{

		@Override
		public void dispose()
		{

		}

		@Override
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
		{

		}

		@Override
		public Object[] getElements(Object inputElement)
		{
			return ((ColumnTableInput) inputElement).getData();
		}

	}

	private ModifyListener createModifyLister_Name()
	{
		return new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e)
			{
				fTableFocus.setTableName(fTableText.getText());
				fEditor.refresh();
			}
		};
	}

	@Override
	protected void updateFields()
	{
		fTableFocus = (Table) fFocusObject;

		if (fTableFocus == null)
		{
			fTableText.setText("");
			fColumnsTable.setInput(new ColumnTableInput(null));
			fStringSizeTable.setInput(new StringSizeTableInput(null));
		}
		else
		{
			fTableText.setText(fTableFocus.getTableName());
			fColumnsTable.setInput(new ColumnTableInput(fTableFocus));
			fStringSizeTable.setInput(new StringSizeTableInput(fTableFocus));
		}
	}

	private class ColumnTableInput
	{
		objects.Table fInput;

		public ColumnTableInput(objects.Table inputTable)
		{
			fInput = inputTable;
		}

		public Object[] getData()
		{
			if (fInput == null)
			{
				return new Object[0];
			}

			return fInput.getColumnNames();
		}
	}

	private class StringSizeTableInput
	{
		objects.Table fInput;

		public StringSizeTableInput(objects.Table inputTable)
		{
			fInput = inputTable;
		}

		public Object[] getData()
		{
			if (fInput == null)
			{
				return new Object[0];
			}

			return fInput.getLargeStringColumns();
		}
	}

}
